<script setup lang="ts">
import {createArray, formatDateTime} from '~/utils';
import {Classify, ExcelDomain, Result, TableFieldVO, UserBO} from "~/api/responseResult";
import {classifyList, saveClassify} from "~/api/warehouse";
import vPinyin from '~/utils/pinyin'
import {TableInfo} from "~/api/requestInstance";
import {ElForm, ElMessage, ElMessageBox} from "element-plus";

const fieldTypeArr = [
  {value: 'NotUsed', label: '不使用'},
  {value: 'text', label: '文本'},
  {value: 'time', label: '时间'},
  {value: 'number', label: '数值'},
]

const userInfo: UserBO = JSON.parse(<string>localStorage.getItem("user"))
const dateTime = formatDateTime(new Date(), 'YYYYMMDDhhmmss')
const props = defineProps<{
  excelDomain: ExcelDomain,
  tableInfo: TableInfo,
  fieldInfo: Map<number, TableFieldVO>,
  operationType: 'CREATE' | 'IMPORT',
  identity: number
}>()

interface TableState {
  excelDomain: ExcelDomain,
  fieldInfo: Map<number, TableFieldVO>,
  tableInfo: TableInfo,
  classifyListData: Array<Classify>,
  importMode: 'ADD' | 'UPDATE' | 'ADD_UPDATE',
  indexes: boolean,
}

const state: TableState = reactive({
  excelDomain: {
    sheetName: '',
    maxColumn: 0,
    tableHead: [],
    tableData: [],
    listMap: [],
  },
  fieldInfo: new Map(),
  tableInfo: {
    tableName: '',
    tableApi: '',
    tableClassifyPid: '',
  },
  classifyListData: [],
  importMode: 'ADD_UPDATE',
  indexes: false,
})

const rules = reactive({
  tableName: [
    {
      required: true,
      message: '请输入表格名称',
      trigger: 'blur',
    },
    {
      min: 1,
      max: 20,
      message: '表格名称过长',
      trigger: 'blur',
    },
  ],
  tableClassifyPid: [
    {
      required: true,
      message: '请选择分类',
      trigger: 'change',
    }
  ]
})

const formRef = ref<InstanceType<typeof ElForm>>();

const turnPinyin = (name: string) => {
  let str = vPinyin.chineseToPinYin(name)
  if (str.length > 30) {
    str = str.slice(0,30)
  }
  return str
}

const initState = () => {
  state.tableInfo = JSON.parse(JSON.stringify(props.tableInfo))
  if (props.operationType == 'CREATE') {
    state.tableInfo.tableApi = turnPinyin(state.tableInfo.tableName) + "_" + userInfo.hrCode + "_" + dateTime
  }
  state.fieldInfo = new Map(props.fieldInfo)
  state.excelDomain = JSON.parse(JSON.stringify(props.excelDomain))
  let on: boolean = false
  state.fieldInfo.forEach((value) => {
    if (value.only) {
      on = true
    }
  })
  state.indexes = on
}
initState()

const getClassifyList = async () => {
  const res: Result<Array<Classify>> = await classifyList()
  if (res.success) {
    state.classifyListData = res.data
  }
}
getClassifyList()

watch(() => state.tableInfo.tableName, (newValue, oldValue) => {
  if (oldValue !== newValue) {
    state.tableInfo.tableApi = turnPinyin(newValue) + "_" + userInfo.hrCode + "_" + dateTime
  }
})

const getTableInfo = (verification: boolean) => {
  let formEl: InstanceType<typeof ElForm> | undefined = formRef.value
  let result = null
  if (verification) {
    if (formEl) {
      formEl.validate((valide: any) => {
        // 只有校验通过，才执行函数
        if (valide) {
          // 校验必填项 默认值是否填写

          let on: boolean = true
          let msg: string = ""
          if (props.operationType === 'IMPORT') {
            state.fieldInfo.forEach(item => {
              if (item.notNull && !item.pid) {
                if (item.fieldType === 'number') {
                  if (item.defaultValue == null || item.defaultValue == '') {
                    on = false
                    msg = msg + item.fieldName + "的默认值不可以为空" + "\n"
                  } else {
                    // 检验格式
                    if (isNaN(item.defaultValue as any as number)) {
                      on = false
                      msg = msg + item.fieldName + "的默认值不正确" + "\n"
                    }
                  }
                } else if (item.fieldType === 'time') {
                  if (item.defaultValue == null || item.defaultValue == '') {
                    on = false
                    msg = msg + item.fieldName + "的默认值不可以为空" + "\n"
                  } else {
                    // 检验格式
                    if (new Date(item.defaultValue) as any == 'Invalid Date') {
                      on = false
                      msg = msg + item.fieldName + "的默认值不正确" + "\n"
                    }
                  }
                } else if (item.fieldType === 'text') {
                  if (item.defaultValue == null || item.defaultValue == '') {
                    on = false
                    msg = msg + item.fieldName + "的默认值不可以为空" + "\n"
                  }
                }
              }
            })
          } else {
            // 创建时必须有一个唯一
            let on1:boolean = true
            state.fieldInfo.forEach(item => {
              if (item.only) {
                on1 = false
              }
            })
            if (on1) {
              on = false
              msg = "必须有一个唯一字段"
            }
          }
          // 检验启用的字段数量
          let num = 0;
          state.fieldInfo.forEach(item => {
            if (item.fieldType !== 'NotUsed' ) {
              num = num + 1
            }
          })
          if (num > 60) {
            on = false
            msg = "字段数量请限制在60以内"
          }
          if (state.tableInfo.tableApi.length > 60) {
            on = false
            msg = "表英文名过长"
          }
          if (on) {
            result = {tableInfo: state.tableInfo, fieldInfo: new Map(state.fieldInfo), importMode: state.importMode}
          } else {
            ElMessage.warning({
              message: msg
            })
          }
        } else {
          console.log("校验失败")
        }
      })
    }
  } else {
    result = {tableInfo: state.tableInfo, fieldInfo: new Map(state.fieldInfo), importMode: state.importMode}
  }
  return result

}

const createCategory = () => {
  ElMessageBox.prompt('请输入分类名称', '保存分类', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
  })
      .then(async ({value}) => {
        const json: any = {}
        json.classifyName = value
        const res: Result<any> = await saveClassify(json)
        if (res.success) {
          ElMessage({
            type: 'success',
            message: `保存成功`,
          })
          await getClassifyList()
        }
      })
      .catch((e) => {
        console.log("失败")
      })
}

const judgmentAuthority = (index: number): boolean => {
  const tableFieldVO: TableFieldVO | undefined = state.fieldInfo.get(index);

  if (tableFieldVO === undefined) {
    return true
  }

  if (props.operationType === 'IMPORT') {

    if (!tableFieldVO.pid) {
      if (props.identity === 1) {
        return false
      } else {
        return true
      }
    } else {
      return false
    }
  } else {
    return false
  }
}
defineExpose({
  fieldTypeArr,
  userInfo,
  dateTime,
  createArray,
  getTableInfo,
  rules,
  formRef,
  createCategory,
  judgmentAuthority
})
</script>

<template>
  <div style="text-align: center;">
    <div v-if="props.operationType === 'CREATE'">
      <h1 style="text-align:left;margin: 20px 0px;font-size: 20px;">基本信息</h1>
      <el-form
          ref="formRef"
          :rules="rules"
          label-width="120px"
          class="demo-ruleForm"
          :model="state.tableInfo"
      >
        <el-row>
          <el-col :span="8">
            <el-form-item label="表格名称" prop="tableName">
              <el-input v-model="state.tableInfo.tableName">
                <template #append>{{ "_" + userInfo.departmentName + "_" + userInfo.realName }}</template>
              </el-input>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item required label="英文">
              <el-input disabled v-model="state.tableInfo.tableApi"/>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item required label="分类" prop="tableClassifyPid">
              <el-select v-model="state.tableInfo.tableClassifyPid" style="width: 60%;" placeholder="请选择分类">
                <el-option
                    v-for="classify in state.classifyListData"
                    :key="classify.pid"
                    :label="classify.classifyName"
                    :value="classify.pid"/>
              </el-select>
              <el-button style="margin-left: 5px;width: 35%" @click="createCategory">创建新分类</el-button>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
    </div>
    <div v-if="props.operationType === 'IMPORT'">
      <el-form
          ref="formRef"
          label-width="120px"
          class="demo-ruleForm"
          :model="{importMode: state.importMode}"
      >
        <el-form-item required label="导入方式">
          <el-select v-model="state.importMode" style="width: 100%;" placeholder="请选择导入方式">
            <el-option label="仅新增数据" value="ADD"/>
            <el-option label="新增数据和更新本人数据（与其他人数据重复时不导入）" value="ADD_UPDATE"/>
            <el-option :disabled="!state.indexes" label="仅更新本人数据（未设置唯一校验时不可使用）" value="UPDATE"/>
          </el-select>
        </el-form-item>
      </el-form>
    </div>
    <div class="_field">
      <h1 style="text-align:left;margin-bottom: 20px;font-size: 20px;">字段配置</h1>
      <el-table
          max-height="400"
          stripe
          border
          :data="state.excelDomain.listMap" style="width: 100%">
        <el-table-column
            v-for="index in createArray(state.excelDomain.maxColumn)"
            :key="index"
            min-width="200"
            :prop="String(index)" :label="state.fieldInfo.get(index) ? state.fieldInfo.get(index).fieldName : ''"
        >
          <template #header>
            <div style="height: 205px;" v-if="state.fieldInfo.get(index)">
              <div>{{ state.fieldInfo.get(index).fieldName }}</div>
              <el-form
                  size="small"
                  label-position="left"
                  label-width="70px"
                  class="demo-ruleForm"
                  :disabled="judgmentAuthority(index)"
              >
                <el-form-item label="字段类型">
                  <el-select
                      :disabled="state.fieldInfo.get(index).pid !== ''"
                      v-model="state.fieldInfo.get(index).fieldType">
                    <el-option
                        v-for="item in fieldTypeArr"
                        :key="item.value"
                        :label="item.label"
                        :value="item.value"
                    >
                    </el-option>
                  </el-select>
                </el-form-item>
                <el-form-item
                    v-if="state.fieldInfo.get(index).fieldType !== 'NotUsed'"
                    label="是否必填">
                  <el-switch
                      :disabled="state.fieldInfo.get(index).pid !== ''"
                      v-model="state.fieldInfo.get(index).notNull"
                      active-color="#13ce66"
                      inactive-color="#ff4949"
                  />
                </el-form-item>
                <el-form-item required
                              v-if="props.operationType === 'IMPORT' && state.fieldInfo.get(index).notNull && state.fieldInfo.get(index).fieldType !== 'NotUsed' && !state.fieldInfo.get(index).pid"
                              label="默认值">
                  <el-input
                      :disabled="state.fieldInfo.get(index).pid !== ''"
                      v-model="state.fieldInfo.get(index).defaultValue"/>
                </el-form-item>
                <el-form-item
                    v-if="state.fieldInfo.get(index).fieldType !== 'NotUsed'"
                    label="是否唯一">
                  <el-checkbox
                      :disabled="state.fieldInfo.get(index).pid !== ''"
                      v-model="state.fieldInfo.get(index).only"
                  ></el-checkbox>
                </el-form-item>
                <el-form-item v-if="state.fieldInfo.get(index).fieldType === 'number'" label="小数位数">
                  <el-input-number
                      :min="0"
                      :max="5"
                      :disabled="state.fieldInfo.get(index).pid !== ''"
                      v-model="state.fieldInfo.get(index).decimalLength"/>
                </el-form-item>
              </el-form>
            </div>
          </template>
        </el-table-column>
      </el-table>
    </div>
  </div>
</template>

<style lang="scss" scoped>
._field {
  ::v-deep .el-form-item--small.el-form-item {
    margin-bottom: 5px;
  }
}
</style>
